#ifndef _IM_CALL_CENTER_SHOP_WAITER_MAP_H_
#define _IM_CALL_CENTER_SHOP_WAITER_MAP_H_

#include <stdint.h>
#include <string>
#include <vector>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/mutex.hpp>

#include "ImServiceCommon_types.h"

namespace base {
class SimpleConnectionPool;
};

namespace imserver {

class ShopWaiterMap {
public:
  static ShopWaiterMap & Instance() {
    static ShopWaiterMap cache;
    return cache;
  }

  int Reload() {
    ReloadShopWaiter();
    ReloadOnlineWaiters();
    return 0;
  }

  // 从waiter映射到shop
  int MapSenderReceiver(int64_t sender, int64_t receiver, int64_t * mapped_sender,
      int64_t * mapped_receiver);

  bool IsWaiter(int64_t qid) const {
    boost::shared_lock<boost::shared_mutex> rlock(waiter_shops_mutex_);
    std::map<int64_t, std::vector<int64_t> >::const_iterator ws_it = waiter_shops_.find(qid);
    return ws_it != waiter_shops_.end();
  }

  bool IsOnlineWaiter(int64_t qid) const {
    boost::shared_lock<boost::shared_mutex> rlock(online_waiters_mutex_);
    std::map<int64_t, SessionType::type>::const_iterator ws_it = online_waiters_.find(qid);
    return ws_it != online_waiters_.end();
  }

  int ReloadShopWaiter();
  int ReloadOnlineWaiters();

private:
  ShopWaiterMap();

  ShopWaiterMap(const ShopWaiterMap &);
  ShopWaiterMap& operator=(const ShopWaiterMap&);

  int64_t GetShopRandomWaiter(int64_t shop) const;
  int64_t GetWaiterRandomShop(int64_t waiter) const;

 private:
  base::SimpleConnectionPool * db_conn_pool_;

  // 店铺的所有客服
  std::map<int64_t, std::vector<int64_t> > shop_waiters_;
  mutable boost::shared_mutex shop_waiters_mutex_;

  // 店铺的在线客服
  std::map<int64_t, SessionType::type> online_waiters_;
  std::map<int64_t, std::vector<int64_t> > shop_online_waiters_;
  mutable boost::shared_mutex online_waiters_mutex_;

  // 客服可以接入的店铺列表
  std::map<int64_t, std::vector<int64_t> > waiter_shops_;
  mutable boost::shared_mutex waiter_shops_mutex_;

  std::map<int64_t, std::map<int64_t, int64_t> > customer_waiter_mapping_;
  std::map<int64_t, std::map<int64_t, int64_t> > waiter_customer_mapping_;
  mutable boost::mutex mapping_mutex_;
};

}

#endif // _IM_CALL_CENTER_SHOP_WAITER_MAP_H_
